package edu.bupt.producerconsumer;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Controller4 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Controller4 resource = new Controller4();
		new Thread(new Producer(resource)).start();
		new Thread(new Producer(resource)).start();
		new Thread(new Consumer(resource)).start();
		new Thread(new Producer(resource)).start();
		new Thread(new Consumer(resource)).start();
	}
	
	private static int number = 0;
	private Queue<Integer> queue = new LinkedList<Integer>();
	private Semaphore mutex = new Semaphore(1);
	private Semaphore notfull = new Semaphore(20);
	private Semaphore notempty = new Semaphore(0);
	
	public void increase(){
		try {
			notfull.acquire();
			mutex.acquire();
			System.out.println(Thread.currentThread().getName() + "生产： " + number);
			queue.offer(number);
			number++;
			notempty.release();
			mutex.release();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
		}
	}
	
	public void decrease(){
		try {
			notempty.acquire();
			mutex.acquire();
			System.out.println(Thread.currentThread().getName() + "消费： " + queue.poll());
			notfull.release();
			mutex.release();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
		}
	}
	static class Producer implements Runnable{
		
		private Controller4 resource;
		public Producer(Controller4 resource) {
			this.resource = resource;
		}

		@Override
		public void run() {
			for(int i = 0 ; i < 10 ; i++){
				resource.increase();
				try {
					Thread.sleep(500);
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
			
		}
		
	}
	
	static class Consumer implements Runnable{
		
		private Controller4 resource;
		public Consumer(Controller4 resource) {
			this.resource = resource;
		}

		@Override
		public void run() {
			for(int j = 0 ;j < 15;j++){
				resource.decrease();
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}
		
	}

	
	
}
